#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include "session.h"
#include "tcp.h"
//处理客户端发来的命令请求
int disClientCmd(int connfd)
{
	unsigned char cmd[100];
	int r = recvData(connfd,cmd,100);
	if(r==-1)
	{
		perror("recvData error");
		return -1;
	}
	
	printf("%s,%d\n",__FUNCTION__,__LINE__);
	int i;
	printf("r = %d\n",r);
	for(i=0;i<r;i++)
		printf("%d ",cmd[i]);
	printf("\n");
	
	//实际读取的命令数据为r个字节
	int len;
	int shutdown=1;
	if(cmd[0] == 0xc0 && cmd[r-1]==0xc0)
	{
		//有效数据
		//根据命令号，进行不同的处理
		switch(cmd[1])
		{
			case FTP_CLOSE_CMD:
				shutdown=disCloseCmd(connfd);
				if(shutdown==-1)
				{
					printf("服务端断开连接\n");
					return -1;
				}
				break;
			case FTP_LS_CMD :
				//处理ls命令
				disLsCmd(connfd);
				break;
			case FTP_UPLOAD_CMD :
				//处理上传文件命令
				len = cmd[2];
				disUpLoadCmd(connfd,&cmd[3]);
				break;
				
			case FTP_DOWNLOAD_CMD :
				//处理下载文件命令
				len = cmd[2];
				disDownLoadCmd(connfd,&cmd[3]);
				break;

		}
	}
}

void disLsCmd(int connfd)
{
	//获取服务端 指定路径下的所有文件名字
	unsigned char data[32];
	int ok = OK;
	unsigned char filename[1024] = "";
	int len = 0;
	
	DIR * p = opendir(PATHNAME);
	if(p == NULL)
	{
		ok = ERROR;
	}
	else
	{
		struct dirent * entp;
		while(1)
		{
			entp = readdir(p);
			if(entp==NULL)
				break;
			//把文件名存到 filename数组中
			//并且要记录下 所有文件名的总长度
			//entp->d_name  ->  filename
			len += sprintf(filename+len,"%s\n",entp->d_name);
		}
	}
	closedir(p);
	//回复客户端一个数据包，表示是否成功
	int i = 0;
	data[i] = 0xc0;
	i++;
	data[i] = ok;
	i++;
	data[i] = 0xc0;
	i++;
	
	sendData(connfd,data,i);
	
	if(ok == OK)//只有成功了，才需要继续回复，回复内容是文件名
	{
		sendData(connfd,filename,len);
	}
	
}


void disDownLoadCmd(int connfd,const char *filename)
{
	unsigned char data[32];
	int ok = OK;
	printf("%s\n",filename);
	char pathname[100] = "";
	sprintf(pathname,"%s/%s",PATHNAME,filename);
	printf("%s\n",pathname);
	int fd = open(pathname,O_RDONLY);
	if(fd == -1)
	{
		perror("");
		ok = ERROR;
		
	}

	int i = 0;
	data[i] = 0xc0;
	i++;
	data[i] = ok;
	i++;
	data[i] = 0xc0;
	i++;
	sendData(connfd,data,i);//回复是否成功
	
	if(ok == OK)//如果成功继续发送文件内容
	{
		char filedata[1024];
		while(1)//循环发送数据，直到全部发送完毕
		{
			int i=0;
			filedata[i++] = 0xc0;//包头
			filedata[i++] = FTP_DOWNLOAD_CMD;
			//data[2] 表示是否为最后一个包，为1时表示是最后一个
			//为0时表示不是最后一个
			int r = read(fd,&filedata[3],1020);
			if(r == 1020)
			{
				filedata[2] = 0;//
			}
			else if(r < 1020)
			{
				filedata[2] = 1;
			}
			
			filedata[r+3] = 0xc0;
			
			sendData(connfd,filedata,r+4);
			
			if(r < 1020)
			{
				break;
			}
		}
		close(fd);
	}
}
void disUpLoadCmd(int connfd,const char *filename)
{
	unsigned char data[32];
	int ok = OK;
	printf("%s\n",filename);
	char pathname[100] = "";
	sprintf(pathname,"%s/%s",PATHNAME,filename);
	printf("%s\n",pathname);
	int fd = open(pathname,O_WRONLY | O_CREAT | O_TRUNC,0664);
	if(fd == -1)
	{
		perror("");
		ok = ERROR;	
	}
	int i = 0;
	data[i] = 0xc0;
	i++;
	data[i] = ok;
	i++;
	data[i] = 0xc0;
	i++;
	int r=sendData(connfd,data,i);//回复是否成功

	unsigned char resp[32];
	r = recvData(connfd,resp,3);//接收服务端的是否成功的数据包
	printf("r=%d\n",r);
	
	for(i=0;i<r;i++)
		printf("%d ",resp[i]);
	printf("\n");

	unsigned char filedata[1024];
	if(resp[0]==0xc0 && resp[r-1]==0xc0)
	{
		
		//有效数据
		if(resp[1]==OK)
		{
			//接着接收客户端发送过来的数据
			//把收到的数据存到服务端本地文件中
			char pathname[100] = "";
			sprintf(pathname,"%s/%s",PATHNAME,filename);
			printf("%s\n",pathname);
			int fd = open(pathname,O_WRONLY | O_CREAT | O_TRUNC,0664);
			if(fd==-1)
			{
				perror("open fail");
			}
			while(1)//循环接收，直到收到客户端发来的最后一个包
			{
				char filedata[1024];
				int r = recvData(connfd,filedata,1024);
				
				write(fd,filedata+3,r-4);//真正文件数据是从filename[3]开始的，并且最后一个字节是包尾
				
				if(filedata[2] == 1)
				{
					break;
				}
			}
			close(fd);
		}
		else
		{
			
			return ;
		}
	}	

	close(fd);
}
int disCloseCmd(int connfd)
{
	//获取服务端 指定路径下的所有文件名字
	unsigned char data[32];
	int ok = OK;
	//回复客户端一个数据包，表示是否成功
	int i = 0;
	data[i] = 0xc0;
	i++;
	data[i] = ok;
	i++;
	data[i] = 0xc0;
	i++;
	sendData(connfd,data,i);
	printf("服务端正在断开连接\n");
	return -1;
		
}






